#pragma once

#include <btBulletDynamicsCommon.h>
#include "baseTypes.h"
#include <string>
#include <vector>

namespace ImpossiblePhysics
{


	// Handle to player's collision object
	extern void* g_playerCollider;

	// Constants
	const std::string ENV_OBJECT         = "ENVIRONMENT_OBJECT";
	const std::string PLAYER_OBJECT      = "PLAYER_OBJECT";
	const std::string GROUND_OBJECT      = "GROUND_OBJECT";
	const std::string KILL_OBJECT        = "KILL_OBJECT";
	const btScalar COLLISION_DEPTH_ERROR = 0.3f;

	// Physics entity
	typedef struct physicsObject
	{
		std::string idString;
		float_t r,g,b;
		bool8_t hit;
		bool8_t dead;
		btScalar top;
		btScalar bottom;
		btScalar depth;
		btRigidBody* body;

		physicsObject(btRigidBody* argRigidBody, std::string idString, float_t r, float_t g, float_t b);
		physicsObject();
	}PhysicsObj;

	// Physics world
	class Physics
	{
	public:
		Physics(void);
		~Physics(void);

		void Init();
		void Update(float_t argDeltaTime);
		const btDynamicsWorld* const GetWorld() const;

		void AddBoxPlayer(PhysicsObj*& argPhysicsEntity,
			float_t argPosX, float_t argPosY ,float_t argPosZ,
			float_t argHalfExtentX, float_t argHalfExtentY, float_t argHalfExtentZ,
			float_t argMass);

		void AddBoxEnvironment(PhysicsObj*& argPhysicsEntity,
			float_t argPosX, float_t argPosY ,float_t argPosZ,
			float_t argHalfExtentX, float_t argHalfExtentY, float_t argHalfExtentZ,
			float_t argMass, std::string argIdString = ENV_OBJECT);

		void AddConeEnvironment(PhysicsObj*& argPhysicsEntity,
			float_t argPosX, float_t argPosY, float_t argPosZ,
			float_t argRadius, float_t argHeight,
			float_t argMass, std::string argIdString = KILL_OBJECT);

	public:
		
		btDynamicsWorld*          m_world;
		btDispatcher*             m_dispatcher;
		btCollisionConfiguration* m_collisionConfig;
		btBroadphaseInterface*    m_broadphase;
		btConstraintSolver*       m_solver;

		const float_t m_fGravity;
	};

}

